import { z } from "zod";
import {
  getAllTasks,
  batchCreateOrUpdateTasks,
  clearAllTasks as modelClearAllTasks,
} from "../../models/taskModel.js";
import { RelatedFileType, Task } from "../../types/index.js";
import { getSplitTasksPrompt } from "../../prompts/index.js";

// 拆分任務工具
// Task splitting tool
export const splitTasksRawSchema = z.object({
  updateMode: z
    .enum(["append", "overwrite", "selective", "clearAllTasks"])
    .describe(
      "任務更新模式選擇：'append'(保留所有現有任務並添加新任務)、'overwrite'(清除所有未完成任務並完全替換，保留已完成任務)、'selective'(智能更新：根據任務名稱匹配更新現有任務，保留不在列表中的任務，推薦用於任務微調)、'clearAllTasks'(清除所有任務並創建備份)。\n預設為'clearAllTasks'模式，只有用戶要求變更或修改計劃內容才使用其他模式"
      // Task update mode selection: 'append' (keep all existing tasks and add new tasks), 'overwrite' (clear all incomplete tasks and completely replace, keep completed tasks), 'selective' (intelligent update: update existing tasks based on task name matching, keep tasks not in the list, recommended for task fine-tuning), 'clearAllTasks' (clear all tasks and create backup). Default is 'clearAllTasks' mode, only use other modes when user requests changes or modifications to plan content
    ),
  tasksRaw: z
    .string()
    .describe(
      "結構化的任務清單，每個任務應保持原子性且有明確的完成標準，避免過於簡單的任務，簡單修改可與其他任務整合，避免任務過多，範例：[{name: '簡潔明確的任務名稱，應能清晰表達任務目的', description: '詳細的任務描述，包含實施要點、技術細節和驗收標準', implementationGuide: '此特定任務的具體實現方法和步驟，請參考之前的分析結果提供精簡pseudocode', notes: '補充說明、特殊處理要求或實施建議（選填）', dependencies: ['此任務依賴的前置任務完整名稱'], relatedFiles: [{path: '文件路徑', type: '文件類型 (TO_MODIFY: 待修改, REFERENCE: 參考資料, CREATE: 待建立, DEPENDENCY: 依賴文件, OTHER: 其他)', description: '文件描述', lineStart: 1, lineEnd: 100}], verificationCriteria: '此特定任務的驗證標準和檢驗方法'}, {name: '任務2', description: '任務2描述', implementationGuide: '任務2實現方法', notes: '補充說明、特殊處理要求或實施建議（選填）', dependencies: ['任務1'], relatedFiles: [{path: '文件路徑', type: '文件類型 (TO_MODIFY: 待修改, REFERENCE: 參考資料, CREATE: 待建立, DEPENDENCY: 依賴文件, OTHER: 其他)', description: '文件描述', lineStart: 1, lineEnd: 100}], verificationCriteria: '此特定任務的驗證標準和檢驗方法'}]"
      // Structured task list, each task should maintain atomicity and have clear completion criteria, avoid overly simple tasks, simple modifications can be integrated with other tasks, avoid too many tasks, example: [{name: 'Concise and clear task name, should clearly express the task purpose', description: 'Detailed task description, including implementation points, technical details and acceptance criteria', implementationGuide: 'Specific implementation methods and steps for this particular task, please refer to previous analysis results to provide concise pseudocode', notes: 'Additional notes, special handling requirements or implementation suggestions (optional)', dependencies: ['Complete name of prerequisite task that this task depends on'], relatedFiles: [{path: 'file path', type: 'file type (TO_MODIFY: to be modified, REFERENCE: reference material, CREATE: to be created, DEPENDENCY: dependency file, OTHER: other)', description: 'file description', lineStart: 1, lineEnd: 100}], verificationCriteria: 'Verification standards and inspection methods for this specific task'}, {name: 'Task 2', description: 'Task 2 description', implementationGuide: 'Task 2 implementation method', notes: 'Additional notes, special handling requirements or implementation suggestions (optional)', dependencies: ['Task 1'], relatedFiles: [{path: 'file path', type: 'file type (TO_MODIFY: to be modified, REFERENCE: reference material, CREATE: to be created, DEPENDENCY: dependency file, OTHER: other)', description: 'file description', lineStart: 1, lineEnd: 100}], verificationCriteria: 'Verification standards and inspection methods for this specific task'}]
    ),
  globalAnalysisResult: z
    .string()
    .optional()
    .describe("任務最終目標，來自之前分析適用於所有任務的通用部分"),
    // Task final objectives, from previous analysis applicable to the common part of all tasks
});

const tasksSchema = z
  .array(
    z.object({
      name: z
        .string()
        .max(100, {
          message: "任務名稱過長，請限制在100個字符以內",
          // Task name is too long, please limit to within 100 characters
        })
        .describe("簡潔明確的任務名稱，應能清晰表達任務目的"),
        // Concise and clear task name, should clearly express the task purpose
      description: z
        .string()
        .min(10, {
          message: "任務描述過短，請提供更詳細的內容以確保理解",
          // Task description is too short, please provide more detailed content to ensure understanding
        })
        .describe("詳細的任務描述，包含實施要點、技術細節和驗收標準"),
        // Detailed task description, including implementation points, technical details and acceptance criteria
      implementationGuide: z
        .string()
        .describe(
          "此特定任務的具體實現方法和步驟，請參考之前的分析結果提供精簡pseudocode"
          // Specific implementation methods and steps for this particular task, please refer to previous analysis results to provide concise pseudocode
        ),
      dependencies: z
        .array(z.string())
        .optional()
        .describe(
          "此任務依賴的前置任務ID或任務名稱列表，支持兩種引用方式，名稱引用更直觀，是一個字串陣列"
          // List of prerequisite task IDs or task names that this task depends on, supports two reference methods, name reference is more intuitive, is a string array
        ),
      notes: z
        .string()
        .optional()
        .describe("補充說明、特殊處理要求或實施建議（選填）"),
        // Additional notes, special handling requirements or implementation suggestions (optional)
      relatedFiles: z
        .array(
          z.object({
            path: z
              .string()
              .min(1, {
                message: "文件路徑不能為空",
                // File path cannot be empty
              })
              .describe("文件路徑，可以是相對於項目根目錄的路徑或絕對路徑"),
              // File path, can be a path relative to the project root directory or an absolute path
            type: z
              .nativeEnum(RelatedFileType)
              .describe(
                "文件類型 (TO_MODIFY: 待修改, REFERENCE: 參考資料, CREATE: 待建立, DEPENDENCY: 依賴文件, OTHER: 其他)"
                // File type (TO_MODIFY: to be modified, REFERENCE: reference material, CREATE: to be created, DEPENDENCY: dependency file, OTHER: other)
              ),
            description: z
              .string()
              .min(1, {
                message: "文件描述不能為空",
                // File description cannot be empty
              })
              .describe("文件描述，用於說明文件的用途和內容"),
              // File description, used to explain the purpose and content of the file
            lineStart: z
              .number()
              .int()
              .positive()
              .optional()
              .describe("相關代碼區塊的起始行（選填）"),
              // Starting line of the related code block (optional)
            lineEnd: z
              .number()
              .int()
              .positive()
              .optional()
              .describe("相關代碼區塊的結束行（選填）"),
              // Ending line of the related code block (optional)
          })
        )
        .optional()
        .describe(
          "與任務相關的文件列表，用於記錄與任務相關的代碼文件、參考資料、要建立的文件等（選填）"
          // List of files related to the task, used to record code files, reference materials, files to be created, etc. related to the task (optional)
        ),
      verificationCriteria: z
        .string()
        .optional()
        .describe("此特定任務的驗證標準和檢驗方法"),
        // Verification standards and inspection methods for this specific task
    })
  )
  .min(1, {
    message: "請至少提供一個任務",
    // Please provide at least one task
  })
  .describe(
    "結構化的任務清單，每個任務應保持原子性且有明確的完成標準，避免過於簡單的任務，簡單修改可與其他任務整合，避免任務過多"
    // Structured task list, each task should maintain atomicity and have clear completion criteria, avoid overly simple tasks, simple modifications can be integrated with other tasks, avoid too many tasks
  );

export async function splitTasksRaw({
  updateMode,
  tasksRaw,
  globalAnalysisResult,
}: z.infer<typeof splitTasksRawSchema>) {
  let tasks: Task[] = [];
  try {
    tasks = JSON.parse(tasksRaw);
  } catch (error) {
    return {
      content: [
        {
          type: "text" as const,
          text:
            "tasksRaw 參數格式錯誤，請確保格式正確，請嘗試修正錯誤，如果文本太長無法順利修復請分批呼叫，這樣可以避免訊息過長導致不好修正問題，錯誤訊息：" +
            // tasksRaw parameter format error, please ensure the format is correct, please try to fix the error, if the text is too long and cannot be fixed smoothly please call in batches, this can avoid messages being too long leading to difficult correction problems, error message: " +
            (error instanceof Error ? error.message : String(error)),
        },
      ],
    };
  }

  // 使用 tasksSchema 驗證 tasks
  // Use tasksSchema to validate tasks
  const tasksResult = tasksSchema.safeParse(tasks);
  if (!tasksResult.success) {
    // 返回錯誤訊息
    // Return error message
    return {
      content: [
        {
          type: "text" as const,
          text:
            "tasks 參數格式錯誤，請確保格式正確，錯誤訊息：" +
            // tasks parameter format error, please ensure the format is correct, error message: " +
            tasksResult.error.message,
        },
      ],
    };
  }

  try {
    // 檢查 tasks 裡面的 name 是否有重複
    // Check if there are duplicate names in tasks
    const nameSet = new Set();
    for (const task of tasks) {
      if (nameSet.has(task.name)) {
        return {
          content: [
            {
              type: "text" as const,
              text: "tasks 參數中存在重複的任務名稱，請確保每個任務名稱是唯一的",
            // Duplicate task names exist in tasks parameter, please ensure each task name is unique
            },
          ],
        };
      }
      nameSet.add(task.name);
    }

    // 根據不同的更新模式處理任務
    // Handle tasks according to different update modes
    let message = "";
    let actionSuccess = true;
    let backupFile = null;
    let createdTasks: Task[] = [];
    let allTasks: Task[] = [];

    // 將任務資料轉換為符合batchCreateOrUpdateTasks的格式
    // Convert task data to format compatible with batchCreateOrUpdateTasks
    const convertedTasks = tasks.map((task) => ({
      name: task.name,
      description: task.description,
      notes: task.notes,
      dependencies: task.dependencies as unknown as string[],
      implementationGuide: task.implementationGuide,
      verificationCriteria: task.verificationCriteria,
      relatedFiles: task.relatedFiles?.map((file) => ({
        path: file.path,
        type: file.type as RelatedFileType,
        description: file.description,
        lineStart: file.lineStart,
        lineEnd: file.lineEnd,
      })),
    }));

    // 處理 clearAllTasks 模式
    // Handle clearAllTasks mode
    if (updateMode === "clearAllTasks") {
      const clearResult = await modelClearAllTasks();

      if (clearResult.success) {
        message = clearResult.message;
        backupFile = clearResult.backupFile;

        try {
          // 清空任務後再創建新任務
        // Clear tasks and then create new tasks
          createdTasks = await batchCreateOrUpdateTasks(
            convertedTasks,
            "append",
            globalAnalysisResult
          );
          message += `\n成功創建了 ${createdTasks.length} 個新任務。`;
          // Successfully created ${createdTasks.length} new tasks.
        } catch (error) {
          actionSuccess = false;
          message += `\n創建新任務時發生錯誤: ${
          // Error occurred when creating new tasks: ${
            error instanceof Error ? error.message : String(error)
          }`;
        }
      } else {
        actionSuccess = false;
        message = clearResult.message;
      }
    } else {
      // 對於其他模式，直接使用 batchCreateOrUpdateTasks
      // For other modes, use batchCreateOrUpdateTasks directly
      try {
        createdTasks = await batchCreateOrUpdateTasks(
          convertedTasks,
          updateMode,
          globalAnalysisResult
        );

        // 根據不同的更新模式生成消息
        // Generate messages based on different update modes
        switch (updateMode) {
          case "append":
            message = `成功追加了 ${createdTasks.length} 個新任務。`;
            // Successfully appended ${createdTasks.length} new tasks.
            break;
          case "overwrite":
            message = `成功清除未完成任務並創建了 ${createdTasks.length} 個新任務。`;
            // Successfully cleared incomplete tasks and created ${createdTasks.length} new tasks.
            break;
          case "selective":
            message = `成功選擇性更新/創建了 ${createdTasks.length} 個任務。`;
            // Successfully selectively updated/created ${createdTasks.length} tasks.
            break;
        }
      } catch (error) {
        actionSuccess = false;
        message = `任務創建失敗：${
        // Task creation failed: ${
          error instanceof Error ? error.message : String(error)
        }`;
      }
    }

    // 獲取所有任務用於顯示依賴關係
    // Get all tasks for displaying dependency relationships
    try {
      allTasks = await getAllTasks();
    } catch (error) {
      allTasks = [...createdTasks]; // 如果獲取失敗，至少使用剛創建的任務
      // If retrieval fails, at least use the newly created tasks
    }

    // 使用prompt生成器獲取最終prompt
    // Use prompt generator to get the final prompt
    const prompt = await getSplitTasksPrompt({
      updateMode,
      createdTasks,
      allTasks,
    });

    return {
      content: [
        {
          type: "text" as const,
          text: prompt,
        },
      ],
      ephemeral: {
        taskCreationResult: {
          success: actionSuccess,
          message,
          backupFilePath: backupFile,
        },
      },
    };
  } catch (error) {
    return {
      content: [
        {
          type: "text" as const,
          text:
            "執行任務拆分時發生錯誤: " +
            // Error occurred when executing task splitting: " +
            (error instanceof Error ? error.message : String(error)),
        },
      ],
    };
  }
}
